package com.xframe.xdal.core.handler;

import com.xframe.xdal.core.constant.RunOpportunity;
import lombok.extern.log4j.Log4j2;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
/**
 * 功能描述: 基于JDBC的查询处理器，将RS返回成对象
 *
 * @author xufeng
 * @version 1.0
 * @date 2023-03-20
 */
@Log4j2
public class BeanObjectHandler<E> implements ResultSetHandler<E>{


    /**
     * 类型 ResultHandler
     */
    private final Class<E> elementBeanType;
    /**
     * 设置的参数对象
     */
    private BeanHandlerOptions beanHandlerOptions;

    public static <E> BeanObjectHandler<E> create(Class<E> beanType,BeanHandlerOptions beanHandlerOptions){
        return new BeanObjectHandler(beanType,beanHandlerOptions);
    }

    public BeanObjectHandler(Class<E> beanType,BeanHandlerOptions beanHandlerOptions){
        this.elementBeanType = beanType;
        this.beanHandlerOptions = beanHandlerOptions;
    }

    @Override
    public E handle(ResultSet resultSet) {
        try {
            if (resultSet == null) {
                return null;
            }
            ResultSetMetaData meta = resultSet.getMetaData();
            int columnCount = meta.getColumnCount();
            boolean isFrist = true;
            E lastBean = null;
            Object lastKey = null;
            while (resultSet.next()) {

                if(isFrist){
                    lastBean = elementBeanType.newInstance();
                    isFrist = false;
                }
                boolean isGetKeyVal = false;
                boolean isRepeatData = false;
                for (int colIndex = 1; colIndex < columnCount + 1; colIndex++) {
                    if(resultSet.getObject(colIndex) != null && beanHandlerOptions.getHandlerColumnMapManage().containsKey(colIndex)) {
                        if(!isGetKeyVal){
                            Object firstVal = beanHandlerOptions.getHandlerColumnMapManage().getValueTaking(resultSet,colIndex);
                            if(lastKey != null && lastKey.equals(firstVal)){
                                // 主键重复
                                isRepeatData = true;

                            }else {
                                beanHandlerOptions.getHandlerColumnMapManage().init();
                                if(lastBean instanceof IAfterConstruction){
                                    afterConstruction(((IAfterConstruction)lastBean));
                                }
                            }
                            lastKey = firstVal;
                            isGetKeyVal = true;
                        }
                        beanHandlerOptions.getHandlerColumnMapManage().setBean(lastBean);
                        if(!isRepeatData){
                            Object val = beanHandlerOptions.getHandlerColumnMapManage().getValueTaking(resultSet,colIndex);
                            beanHandlerOptions.getHandlerColumnMapManage().setValueStrategy(val,colIndex);
                        }else {
                            beanHandlerOptions.getHandlerColumnMapManage().setValueListStrategy(resultSet,colIndex);
                        }
                    }
                }
                beanHandlerOptions.getHandlerColumnMapManage().setLineEnd(beanHandlerOptions.getAutoProcRuntime());
            }


            this.beanHandlerOptions.getAutoProcRuntime().autoFill(lastBean,this.beanHandlerOptions.getTableInfo(), RunOpportunity.R);
            if(lastBean instanceof IBeanInit){
                ((IBeanInit)lastBean).init();
            }
            return lastBean;
        } catch (Exception exception) {
            log.error("exception={}",exception);
            return null;
        }
    }

    protected void afterConstruction(IAfterConstruction bean){
        try{
            bean.build();
        }catch (Exception exception){
            exception.printStackTrace();
        }
    }
}
